from Driver.IosDriver import IosDriver
from Driver.AndroidDriver import AndroidDriver
from Driver.BaseDriver import BaseDriver
from Common import *


class DriverManager(object):

    def __init__(self):
        self._clients = {'android': {}, 'ios': {}}

    def get_devices(self, platform: str):
        """
        获取设备列表
        :param platform: 平台
        :return:
        """
        platform = platform.lower()
        if platform == "ios":
            return IosDriver.get_devices()
        elif platform == "android":
            return AndroidDriver.get_devices()
        else:
            raise ClientRunError("platform [{}] not support!".format(platform))

    def _format_serial(self, serial: str) -> str:
        """
        格式化序列号
        :param serial:
        :return:
        """
        return serial.replace(".", "-").replace(":", "-")

    def get_sessions(self, platform: str):
        platform = platform.lower()
        if platform == "ios" or platform == "android":
            return [k for k in self._clients[platform] if self._clients[platform][k].status == 'connect']
        else:
            raise ClientRunError("platform [{}] not support!".format(platform))

    def _get_driver(self, serial: str):
        for s in self._clients.values():
            try:
                return s[serial]
            except:
                continue
        return None

    def get_driver(self, serial: str = None, platform: str = None):
        if serial is None and platform is None:
            raise ManagerError("serial or platform must contain at least one")
        if serial is None:
            serial = self.get_devices(platform)[0]
        driver = self._get_driver(self._format_serial(serial))
        if driver is None:
            driver = IosDriver(serial) if platform.lower() == 'ios' else AndroidDriver(serial)
            self._clients[platform.lower()][self._format_serial(serial)] = driver
        return driver

    def function_support(self, prefix, args):
        if prefix in ['env']:
            return 'get_' + args[0]
        for s in BaseDriver.get_method_names(prefix):
            if s.split('_')[-1] == args[-1]:
                return s
        return None

    def args_support(self, func_name, args_list):
        func_args = BaseDriver.get_method_args(func_name)
        if list(set(func_args).difference(set(args_list))):
            return False
        else:
            return True

    def args_define(self, func_name):
        return BaseDriver.get_method_args(func_name)

    def build_args(self, func_name, args):
        res_dict = {}
        for param in self.args_define(func_name):
            try:
                res_dict[param] = args[param]
            except:
                pass
        return res_dict
